#include "visitor.h"
#include "stmt.h"
#include "symbol.h"
#include "opcode.h"
#include "debug.h"
#include "flow.h"
#include "ssa.h"
#include "codegen.h"
#include <cstdio>
#include <vector>
#include <fstream>

extern FILE *yyin;
using namespace std;

extern int yyparse();
//extern vector<Tree*> statements;

Tree *program_node = 0;
extern SymbolTable symbolTable;

extern void RegAnalysis(CFG *cfg);

int main(int argc, char *argv[]){
    FILE *f;
    f = fopen(argv[1],"r");
    yyin = f;
    yyparse();
    //Block *blk = dynamic_cast<Block*>(program_node);
    FunctionSymbol *sym = new FunctionSymbol(new string("_main_"),0);
    Program::globalContext = new Context(sym);
    sym->context = Program::globalContext;
    Scope::curScope = new Scope(0);
    Context::curContext = Program::globalContext;
    FunctionManager::getInstance()->functions.push_back(sym);
    SymbolEnter v;
    program_node->accept(&v);

    OpCodeGen c;
//    for(it = statements.begin();it != statements.end();it++){
//        (*it)->accept(&c);
//    }
    program_node->accept(&c);
    c.printInfo();
    FunctionManager *mng = FunctionManager::getInstance();
    FunctionManager::iterator   it;
    ofstream os("g.dot");
    GraphPrinter gp(os);
    gp.beginGraph();
    for(it = mng->functions.begin();it != mng->functions.end();it++){
        (*it)->cfg = new CFG((*it));
        (*it)->cfg->setup();
        DomTree *domTree = (*it)->cfg->getDomTree();
        (*it)->cfg->printBlocks(gp);
        if(!domTree){
            continue;
        }
        domTree->buildDomTree();
        domTree->buildDomFrontier();
        domTree->printBlocks(gp);

        // LiveAnalysis *live = new LiveAnalysis((*it)->cfg);
        // live->buildLiveness();
        // live->printBlocks();
        RegAnalysis((*it)->cfg);
        X86Codegen codegen;
        codegen.genCode((*it)->cfg);
    }
    gp.endGraph();
    //if(program_node)
     //   program_node->accept(v);
    //printf("result is %d\n",program_node->evalStatement());
    //symbolTable.printInfo();
}
